/*
The purpose of this file is to link the nodes to the parser, assign the customized lexer to the parser
and expose the methods 'parse' and 'tokenize' publicly.
This effectively makes the generated parser, customized lexer, and specified nodes useable.
*/
(function() {

    var buildParser, parser, lexer, nodes;

    nodes = require('./nodes');
    lexer = require('./lexer');

    buildParser = function(opts) {

        var parser;
        parser = require('./gen_parser').parser;
        opts = opts || {};
        parser.args = opts.args || [];
        parser.placeholders = opts.placeholders || [];
        parser.escFn = opts.escFn || function(v) {
            return v;
        };

        parser.lexer = {
            lex: function() {
                var tag, _ref;
                _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
                return tag;
            },
            setInput: function(tokens) {
                this.tokens = tokens;
                return this.pos = 0;
            },
            upcomingInput: function() {
                return "";
            }
        };

        parser.yy = nodes;
        parser.throwUnMatchedParamsExc = function() {
            return parser.parseError("number of '?'s in statement string does not match argument count", {});
        };

        return parser;

    };

    parser = buildParser();

    exports.parse = function(sql) {
        return parser.parse(lexer.tokenize(sql));
    };

    exports.parse2 = function(sql, opts) {

        var args, paramsLength, placeholders, tokenInfo, tokens;

        tokenInfo = lexer.tokenize2(sql, opts);
        tokens = tokenInfo.tokens;
        placeholders = tokenInfo.placeholders;
        paramsLength = placeholders.length;
        args = opts.args || [];

        if (paramsLength < 1 && args.length < 1) {
            return parser.parse(tokens);
        }

        if (args.length > 0 && paramsLength < 1) {
            parser.throwUnMatchedParamsExc();
        }

        opts.placeholders = placeholders;

        return buildParser(opts).parse(tokens);

    };

    //expose as public properties of sql_parser
    exports.throwUnMatchedParamsExc = parser.throwUnMatchedParamsExc;
    exports.parser = parser;
    exports.lexer = lexer;
    exports.nodes = nodes;

}).call(this);